package com.monas.client.jfree;

import java.sql.Timestamp;
import java.util.Date;
import java.util.LinkedList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.experimental.chart.swt.ChartComposite;

import com.monas.client.dialog.ChartDialog;

/**
 * Class composite untuk membuat chart time line.
 * 
 * @author ekowahyudi
 * 
 */
public class MonasTimeLineChartComposite {

	private static final long MINUTE = 60 * 1000;
	private static final long HOUR = 60 * MINUTE;

	private final String title;
	private final String xLabel;
	private final String yLabel;

	private Composite panel = null;

	private MonasTimeLineChart chart;

	public MonasTimeLineChartComposite(Composite parent, String title,
			String xLabel, String yLabel) {

		this.title = title;
		this.xLabel = xLabel;
		this.yLabel = yLabel;

		/*
		 * Buat panel
		 */
		panel = new Composite(parent, SWT.BORDER);

		/*
		 * Siapkan layout untuk mengatur panel
		 */
		panel.setLayoutData(new GridData(GridData.FILL_BOTH));

		panel.setLayout(new FillLayout());
	}

	public void refresh() {
		chart.clearData();
		addRandomData(chart);
	}

	public void createDefaultChart() {
		createRandomChart();

		createComposite(chart);
	}

	public void createComposite(MonasTimeLineChart chart) {
		createComposite(panel, chart);
	}

	public void createComposite(final Composite panel, MonasTimeLineChart chart) {
		this.chart = chart;
		ChartComposite frame = new ChartComposite(panel, SWT.NONE,
				chart.getChart(), true);
		frame.setDisplayToolTips(true);
		frame.setHorizontalAxisTrace(false);
		frame.setVerticalAxisTrace(false);

		// untuk tidak menampilkan chart dalam bentuk zoom.
		frame.setRangeZoomable(false);
		frame.setDomainZoomable(false);

		frame.addChartMouseListener(new ChartMouseListener() {

			@Override
			public void chartMouseMoved(ChartMouseEvent event) {
			}

			@Override
			public void chartMouseClicked(ChartMouseEvent event) {
				if (event.getEntity() instanceof XYItemEntity) {
					XYItemEntity entity = (XYItemEntity) event.getEntity();
					if (entity != null) {
						// indeks dari series yang di-click
						int index = entity.getSeriesIndex();
						// urutan item yang di-click
						int item = entity.getItem();

						TimeSeriesCollection dataset = (TimeSeriesCollection) entity
								.getDataset();
						int totalItem = dataset.getItemCount(index);
						TimeSeries series = dataset.getSeries(index);

						LinkedList<ChartValue> values = new LinkedList<ChartValue>();
						for (int i = 0; i < totalItem; i++) {
							ChartValue value = new ChartValue(dataset.getX(
									index, i), dataset.getY(index, i));
							values.add(value);
						}

						ChartDialog dialog = new ChartDialog(panel.getShell(),
								series, values, item);
						dialog.open();
					}
				}
			}

		});
	}

	public MonasTimeLineChart createChart() {
		return new MonasTimeLineChart(title, xLabel, yLabel);
	}

	private void createRandomChart() {
		MonasTimeLineChart chart = new MonasTimeLineChart(title, xLabel, yLabel);
		addRandomData(chart);
		chart.createChart();
	}

	private void addRandomData(MonasTimeLineChart chart) {
		Date currentDate = new Date();
		Date beforeDate = new Date(currentDate.getTime() - HOUR);

		LinkedList<Timestamp> times = new LinkedList<Timestamp>();
		for (int i = 0; i < 10; i++) {
			times.add(new Timestamp(beforeDate.getTime() + (i * 2 * MINUTE)));
		}

		for (int i = 0; i < 5; i++) {
			String label = "Server " + (i + 1);

			LinkedList<Number> values = new LinkedList<Number>();
			for (int j = 0; j < 10; j++) {
				Double value = Math.random() * 100;
				values.add(value);
			}
			chart.addTimeSeries(label, times, values);
		}
	}

	public MonasTimeLineChart getChart() {
		return chart;
	}
}
